<template>
<div>
    <!-- 搜索组件一级路由   $router.back()返回上一个页面-->
    <van-nav-bar
      left-arrow
      title="搜索中心"
      @click-left="$router.back()">
    </van-nav-bar>

    <!-- https://youzan.github.io/vant/#/zh-CN/search
      input: 当输入内容变化时，它会触发
    -->
    <van-search
      show-action
      placeholder="请输入搜索关键词"
      shape="round"
      v-model.trim="keyword"
      @input="hGetSuggestion_with_fang_dou"
      >
      <div slot="action" @click="hSearch">搜索</div>
    </van-search>

    <!-- 联想建议
    v-html来正常显示html字符串效果-->
    <van-cell-group v-if="keyword">
      <van-cell
      v-for="(item, idx) in cSuggestion"
      :key="idx"
      @click="hSearchSuggestion(idx)"
      icon="search">
        <div v-html="item"></div>
      </van-cell>
    </van-cell-group>
    <!-- /联想建议 -->

    <!-- 搜索历史记录 -->
    <van-cell-group v-else>
      <van-cell title="历史记录"></van-cell>
      <van-cell v-for="(item,idx) in history"
        :key="idx"
        :title="item"
        @click="$router.push('/search/result?keyword='+item)">
         <van-icon name="close" @click.stop="hDeleteHistory(idx)"/>
      </van-cell>
    </van-cell-group>
    <!-- /搜索历史记录 -->
  </div>
</template>

<script>
import { setItem, getItem } from '@/utils/storage'
import { getSuggestion } from '@/api/search'
import _ from 'lodash'

// 消除魔术数
const SEARCHHISTORY_KEY = 'searchHistory'

export default {
  name: 'Search',
  data () {
    return {
      // 初始化，先从本地存储中取值，取不到，则用[]
      history: getItem(SEARCHHISTORY_KEY) || [], // 保存搜索记录
      suggestion: [], // 搜索建议
      keyword: '' // 搜索关键字
    }
  },
  computed: {
    // 用箭头函数对代码进行精简
    cSuggestion () {
      // 根据keyword，对 suggestion中的每一项进行正则替换，达到
      // 高亮的效果
      const regexp = new RegExp(this.keyword, 'gi')
      return this.suggestion.map(str => str.replace(regexp, obj => `<span style="color:red;">${obj}</span>`))
    }
    // cSuggestion () {
    //   // 根据keyword，对 suggestion中的每一项进行正则替换，达到
    //   // 高亮的效果
    //   const regexp = new RegExp(this.keyword, 'gi')
    //   const arr = this.suggestion.map(str => {
    //     return str.replace(regexp, (obj) => {
    //       return `<span style="color:red;">${obj}</span>`
    //     })
    //   })
    //   return arr
    // }
  },
  methods: {
    // 搜索的第1种方式
    // 用户在 搜索建议项 上 点击了一次
    hSearchSuggestion (idx) {
      // console.log(this.suggestion[idx])
      // 1. 把当前的搜索建议添加到搜索记录中
      this.addHistory(this.suggestion[idx])
      // 2. 跳转路由，进入搜索结果页
      this.$router.push({
        // 路由地址
        path: '/search/result',
        // 通过query传递参数
        query: {
          keyword: this.suggestion[idx]
        }
      })
    },
    // 搜索的第2种方式
    // 用户点击搜索按钮
    hSearch () {
      if (this.keyword === '') {
        return
      }
      // 1. 把当前的搜索建议添加到搜索记录中
      this.addHistory(this.keyword)

      // 2. 跳转路由，进入搜索结果页
      this.$router.push({
        // 路由地址
        path: '/search/result',
        // 通过query传递参数
        query: {
          keyword: this.keyword
        }
      })
    },
    // 用来向搜索记录中添加新项str
    // 搜索记录的基本规则
    // - 1. 不能有重复的项
    // - 2. 最近搜索记录应该放在最前面
    addHistory (str) {
      console.log('调用addHistory', str, '加入到搜索历史数组中')
      // 历史记录是一个数组，但，它不应该出现重复项
      const idx = this.history.findIndex(it => it === str)
      if (idx !== -1) {
        // 说明在历史记录中已经有这一项
        // 应该删除掉
        this.history.splice(idx, 1)
      }

      // 把当前的要添加的内容放在数据的最前面
      // unshift是在数组的前面添加，而push是在最后追加
      this.history.unshift(str)

      // 对更新后的历史记录进行本地持久化
      setItem(SEARCHHISTORY_KEY, this.history)
    },
    // 用户点击了删除历史记录
    hDeleteHistory (idx) {
      this.history.splice(idx, 1)

      // 对更新后的历史记录进行本地持久化
      setItem(SEARCHHISTORY_KEY, this.history)
    },
    async hGetSuggestion () {
      // 1. 检查当前的关键是否为空
      if (this.keyword === '') {
        this.suggestion = []
        return
      }
      // 2. 调用方法，发请求
      const result = await getSuggestion(this.keyword)

      // 3. 把请求结果保存在数据项中
      console.log(result, this.keyword)

      this.suggestion = result.data.data.options
    },
    // hGetSuggestion_with_fang_dou_lodash 是一个属性名
    // _.debounce(function(){}, 500) : 它是一个函数调用，debounce这个函数需要传入两个参数
    // 第一个参数： 需要进行防抖处理的函数
    // 第二个参数： 时间
    // 它的返回值仍是一个函数，就是对参数1采用 500ms防抖处理的函数
    hGetSuggestion_with_fang_dou_lodash: _.debounce(async function () {
      // 1. 检查当前的关键是否为空
      if (this.keyword === '') {
        this.suggestion = []
        return
      }
      // 2. 调用方法，发请求
      const result = await getSuggestion(this.keyword)

      // 3. 把请求结果保存在数据项中
      console.log(result, this.keyword)

      this.suggestion = result.data.data.options
    }, 500),
    hGetSuggestion_with_jie_liu_lodash: _.throttle(async function () {
      // 1. 检查当前的关键是否为空
      if (this.keyword === '') {
        this.suggestion = []
        return
      }
      // 2. 调用方法，发请求
      const result = await getSuggestion(this.keyword)

      // 3. 把请求结果保存在数据项中
      console.log(result, this.keyword)

      this.suggestion = result.data.data.options
    }, 500),
    // 对搜索方法进行防抖处理
    hGetSuggestion_with_fang_dou () {
      // 以防抖5s为例：
      // 当这个函数调用时，它不会立刻执行核心代码，而在5s之后去执行
      // 如果在5s内，它被再次调用，则从当前被调用的时间开始算，再向后延迟5s执行。

      if (this.timer) {
        clearTimeout(this.timer)
      }

      this.timer = setTimeout(() => {
        this.hGetSuggestion()
      }, 0.05 * 1000)
    },
    // 对搜索方法进行节流处理
    hGetSuggestion_with_jie_liu () {
      console.log('hGetSuggestion_with_jie_liu', (new Date()).toLocaleTimeString(), this.keyword)
      // 以节流5s为例
      // 如果这个函数被调用，检查它距离上一次被调用的时间是否相隔>=5s，是就执行；否则，本次调用就不
      // 执行代码
      // 两次执行的时间，至少相隔5s
      if (this.timer) {
        return
      }

      this.timer = setTimeout(async () => {
        this.timer = null

        // 1. 检查当前的关键是否为空
        if (this.keyword === '') {
          this.suggestion = []
          return
        }
        // 2. 调用方法，发请求
        const result = await getSuggestion(this.keyword)

        // 3. 把请求结果保存在数据项中
        console.log(result, this.keyword)

        this.suggestion = result.data.data.options
      }, 5 * 1000)
    }
  }
}
</script>

<style lang="" scoped>

</style>
